<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>手写call方法</title>
</head>

<body>

  <script>
    /**
     *  手写 call 方法
     *   1. 定义 myCall 方法
     *   2. 设置 this 并调用原函数   隐患：如果有同名属性就会发生冲突
     *   3. 接收剩余参数并返回结果
     *   4. 使用 Symbol 调优
     *  */
    // 1. 定义 myCall 方法
    // 3. 接收剩余参数并返回结果
    Function.prototype.myCall = function (thisArg, ...args) {
      // 2. 设置 this 并调用原函数
      // thisArg 就是需要设置为 this 的对象
      // this 原函数(原函数.myCall)
      // 需要给 thisArg 加一个一定和原属性不重名的新属性
      // 4. 使用 Symbol 调优
      const key = Symbol('key')
      thisArg[key] = this
      // 将 key 解析为 [] 不能用 . 调用方法
      // 否则就变为了 thisArg 的 key 属性
      const res = thisArg[key](...args)
      delete thisArg[key]
      return res
    }

    //  测试代码
    const person = {
      name: 'Ali'
    }
    function func(numA, numB) {
      console.log(this)
      console.log(numA, numB)
      return numA + numB
    }
    const res = func.myCall(person, 2, 8)
    console.log('返回值为', res)


  </script>
</body>

</html>